﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Autofac;
using hello.csharp.controller;
using hello.csharp.kernel;
using hello.csharp.zone.Swaggers;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using NLog;
using Swashbuckle.AspNetCore.Swagger;
using Swashbuckle.AspNetCore.SwaggerGen;

namespace hello.csharp.zone
{
    public class Startup
    {
        private static readonly ILogger _Logger = LogManager.GetCurrentClassLogger();
        private readonly string _projectName;

        public Startup(IConfiguration configuration)
        {
            _projectName = GetType().Namespace;
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        /// <summary>
        /// This method gets called by the runtime. Use this method to add services to the container.
        /// </summary>
        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
            services.AddSwaggerGen(c =>
            {
                typeof(ApiVersions).GetEnumNames().ToList().ForEach(version =>
                {
                    c.SwaggerDoc(version, new Info
                    {
                        Version = version,
                        Title = $"{_projectName} 接口文档"
                    });
                });
                SwaggerIncludeXml(c);
                c.OperationFilter<AssignOperationVendorExtensions>();
                c.DocumentFilter<ApplyTagDescriptions>();
            });
        }

        /// <summary>
        /// 在Swagger调用WebApi时显示参数的注释
        /// </summary>
        private void SwaggerIncludeXml(SwaggerGenOptions c)
        {
            //在项目属性中手工定义的输出文件
            var location = Assembly.GetEntryAssembly().Location;
            var dir = new DirectoryInfo(location);
            var dirName = Directory.GetDirectoryRoot(location);
            if (dir.Parent != null)
                dirName = dir.Parent.FullName;
            var xml = Path.Combine(dirName, $"{_projectName}.xml");
            c.IncludeXmlComments(xml);//在Swagger调用WebApi时显示参数的注释
            _Logger.Info($"Swagger加载完成。xml文件路径:{xml}");
        }

        /// <summary>
        ///     本函数用来设定基于autofac的注入。
        /// </summary>
        /// <param name="builder">Autofac的ContainerBuilder</param>
        public void ConfigureContainer(ContainerBuilder builder)
        {
            IoCManager.Instance.Register(builder);
        }

        /// <summary>
        /// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        /// </summary>
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios,
                // see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseSwagger();
            app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", ApiVersions.v1.ToString()); });

            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseCookiePolicy();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}
